package uk.ac.standrews.cs.cs2001.practical02.interfaces;

import java.util.Date;

import uk.ac.standrews.cs.cs2001.practical02.common.NoCopiesException;
import uk.ac.standrews.cs.cs2001.practical02.common.NotBorrowedException;

/**
 * Interface for a simple lending library ADT.
 * 
 * @author eb
 */
public interface ILibrary {

	/**
	 * Adds a copy of the specified book to the library.
	 * 
	 * @param book the book to be added
	 */
	void addCopy(IBook book);

	/**
	 * Borrows a copy of the specified book from the library.
	 * 
	 * @param book the book to be borrowed
	 * @param date the date on which the book is borrowed
	 * @throws NoCopiesException if no copies of the book are available to be borrowed
	 */
	void borrowCopy(IBook book, Date date) throws NoCopiesException;

	/**
	 * Returns a copy of the specified book to the library.
	 * 
	 * @param book the book to be returned
	 * @param date the date on which the book is returned
	 * @throws NotBorrowedException if no copies of the book are currently borrowed
	 */
	void returnCopy(IBook book, Date date) throws NotBorrowedException;
	
	/**
	 * Gets the total number of books belonging to the library. Multiple copies of the same book
	 * only count once. The count includes books that are present in the library and books
	 * that are currently borrowed.
	 * 
	 * @return the total number of books
	 */
	int getNumberofBooks();
	
	/**
	 * Gets the total number of book copies in the library. For example, returns 3 if
	 * there are 2 copies of one book and 1 copy of another book. The count includes books that are present in the library and books
	 * that are currently borrowed.
	 * 
	 * @return the total number of book copies
	 */
	int getNumberOfCopies();
	
	/**
	 * Gets the total number of copies in the library of a given book. The count includes books that are present in the library and books
	 * that are currently borrowed.
	 * 
	 * @param book the book
	 * @return the total number of copies of the book
	 */
	int getNumberOfCopies(IBook book);
	
	/**
	 * Gets the total number of copies of a given book that are available for borrowing.
	 * 
	 * @param book the book
	 * @return the total number of available copies of the book
	 */
	int getNumberAvailable(IBook book);
	
	/**
	 * Gets the total number of times that a given book has been borrowed.
	 * 
	 * @param book the book
	 * @return the total number of times that the book has been borrowed
	 */
	int getNumberOfBorrowings(IBook book);
	
	/**
	 * Gets the book that has been borrowed the greatest number of times. The behaviour
	 * is undefined if there is not a single most popular book.
	 * 
	 * @return the book that has been borrowed the greatest number of times
	 */
	IBook getMostPopular();
	
	/**
	 * Gets the book that has been most recently borrowed.
	 * 
	 * @return the book that has been most recently borrowed, or null if no books have been borrowed
	 */
	IBook getMostRecentlyBorrowed();
}
